package com.nlx.notes.support.interceptor;

import com.nlx.notes.module.bean.dto.context.UserContext;
import com.nlx.notes.module.bean.vo.ResultVO;
import com.nlx.notes.module.bean.vo.accountbook.AccountBookVO;
import com.nlx.notes.module.core.consts.RedisConst;
import com.nlx.notes.module.core.util.JSONUtils;
import com.nlx.notes.module.entity.Users;
import com.nlx.notes.module.service.IAccountBooksService;
import com.nlx.notes.support.context.UserHolder;
import com.nlx.notes.support.helper.redis.RedisHelper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class TokenInterceptor implements HandlerInterceptor {

    public static final String[] SQL_PATTERNS = {
            "sleep(", "benchmark(", "union select", " information_schema ",
            " or 1=1", "drop table", "--", "/*", "*/"
    };

    public static final String[] JNDI_PATTERNS = {
            "${jndi:", "ldap://", "rmi://", "${"
    };



    private static final List<String> NEED_PASS_URL_LIST = new ArrayList<>();


    static {
        NEED_PASS_URL_LIST.add("/incExp/login/v1/guest");
        NEED_PASS_URL_LIST.add("/incExp/user/v1/user-code");
        NEED_PASS_URL_LIST.add("/incExp/test/init-data");
    }

    final RedisHelper redisHelper;

    final IAccountBooksService accountBooksService;

    public TokenInterceptor(RedisHelper redisHelper, IAccountBooksService accountBooksService) {
        this.redisHelper = redisHelper;
        this.accountBooksService = accountBooksService;
    }


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
//        log.info("进入了拦截器中,url:{}",request.getRequestURI());
        Map<String, String[]> params = request.getParameterMap();
        for (String key : params.keySet()) {
            for (String value : params.get(key)) {
                if (isMalicious(value)) {
                    response.sendError(400, "Illegal input detected.");
                    return false;
                }
            }
        }
//        Enumeration<String> headerNames = request.getHeaderNames();
//        while (headerNames.hasMoreElements()) {
//            String header = headerNames.nextElement();
//            String value = request.getHeader(header);
//
//            if (isMalicious(value)) {
//                response.sendError(400, "Illegal header detected.");
//                return false;
//            }
//        }

        String token = request.getHeader("Authorization");
        if(request.getRequestURI().contains("png")){
            return true;
        }
        if(NEED_PASS_URL_LIST.contains(request.getRequestURI())){
            return true;
        }
        if (token == null) {
            log.error("没有获取到token信息");
            response.setContentType("application/json;charset=UTF-8");
            ResultVO<?> result = ResultVO.error(401,"未登录或Token无效");
            response.getWriter().write(JSONUtils.toString(result));
            return false;
        }
        if (null != UserHolder.getUserContext()) {
            UserHolder.removeUserContext();
        }
//        log.info("url: ->{},user token ->{}",request.getRequestURI(),token);
        Users user = redisHelper.getKey(token, Users.class);
        if (user == null) {
            log.error("redis中没有token信息");
            response.setContentType("application/json;charset=UTF-8");
            ResultVO<?> result = ResultVO.error(401,"未登录或Token无效");
            response.getWriter().write(JSONUtils.toString(result));
            return false;
        }
        redisHelper.ttlKey(token, RedisConst.Token.USER_LOGIN_TOKEN_TIMOUT_LIMIT,
                RedisConst.Token.USER_LOGIN_TOKEN_TIMOUT_LIMIT_unit);
//        log.info("获取到的用户信息：{}",JSONUtils.toString(user));
        UserContext userContext = new UserContext();
        userContext.setId(user.getId());
        userContext.setUsername(user.getUsername());
        userContext.setUserPhone(user.getUserPhone());
        userContext.setEmail(user.getEmail());
        userContext.setCreatedAt(user.getCreatedAt());
        userContext.setToken(token);
        //获取账本信息
        AccountBookVO currentBook = accountBooksService.getCurrentBook(user.getId());
        userContext.setBookId(currentBook.getId());
        UserHolder.setUserContext(userContext);
        return true;
    }


    private boolean isMalicious(String input) {
        if (input == null) return false;
        String value = input.toLowerCase();

        // SQL 注入特征
        for (String sql : SQL_PATTERNS) {
            if (value.contains(sql)) {
                log.error("敏感数据：{}",value);
                return true;
            }
        }

        // Log4j 注入特征
        for (String jndi : JNDI_PATTERNS) {
            if (value.contains(jndi)) {
                log.error("敏感数据：{}",value);
                return true;
            }
        }

        return false;
    }


}
